/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "file_载入保存数据.h"
#include "字符串数值互换.h"
#include "file_文件名数据.h"

#include <filesystem>

using namespace std;


//#ifdef _DEBUG
//#pragma comment(lib, "libboost_locale-vc142-mt-sgd-x64-1_71.lib")
//#else
//#pragma comment(lib, "libboost_locale-vc142-mt-s-x64-1_71.lib")
//#endif // DEBUG





void* f_打开文件(uint32* size, const string path) {
	FILE* f;
	f = fopen(path.c_str(), "rb");

	fseek(f, 0L, SEEK_END);

	*size = ftell(f);
	//void* data = malloc((*size + 1) * sizeof(uint8));
	void* data = malloc((*size) + 1);

	if (data) {
		rewind(f);
		fseek(f, 0L, SEEK_SET);
		fread(data, *size, 1, f);
		//fread(data, sizeof(uint8), *size, f);
		((uint8*)data)[*size] = 0;
	}
	else return 0;

	fclose(f);


	return data;

}

void f_保存文件(const void* data[], const uint32* size, const uint32 num, const string path, const bool 是否备份保存) {
	std::filesystem::path tmpPath(path);

	bool 是否有老文件 = false;
	string 保存路径 = path;
	string 文件名 = tmpPath.stem().string();
	string 临时文件路径 = tmpPath.parent_path().string() + "/tme_" + 文件名 + ".tmp";
	//string 老临时文件 = 临时文件路径;

	//目录是否存在
	if (std::filesystem::exists(tmpPath.parent_path().string()) == false) {
		std::filesystem::create_directories(tmpPath.parent_path().string());
	}

	if (是否备份保存) {
		if (std::filesystem::exists(tmpPath)) {
			保存路径 = 临时文件路径;
			是否有老文件 = true;
		}

	}




	FILE* f;
	f = fopen(保存路径.c_str(), "wb");
	if (f) {
		for (uint32 i = 0; i < num; ++i) {
			fwrite(&size[i], sizeof(uint32), 1, f);
			fwrite(data[i], 1, size[i], f);
			//float32 v = ((float32*)data[i])[0];
		}
		
		fclose(f);
	}
	




	if (是否有老文件) {
		//把老文件备份
		std::filesystem::path 备份文件名(tmpPath.parent_path().string() + "/Backup_" + 文件名 + ".tmp");
		std::filesystem::rename(tmpPath, 备份文件名);

		//临时文件改层主文件名
		std::filesystem::rename(保存路径, tmpPath);
	}


}

void f_写入文件(FILE* f, const vector<float32>& data) {
	uint32 num = data.size();
	fwrite(&num, sizeof(uint32), 1, f);
	fwrite(data.data(), sizeof(float32), data.size(), f);
}

void f_读入文件(FILE * f, vector<float32>* data) {
	uint32 num = 0;
	fread(&num, sizeof(uint32), 1, f);
	(*data).resize(num);
	fread((*data).data(), sizeof(float32), (*data).size(), f);
}



void f_写入文件(FILE* f, const std::vector<std::vector<float32>>& data) {
	uint32 num = data.size();
	fwrite(&num, sizeof(uint32), 1, f);

	for (const auto& d : data) {
		f_写入文件(f, d);
	}
	
}

void f_读入文件(FILE* f, std::vector<std::vector<float32>>* data) {
	uint32 num = 0;
	fread(&num, sizeof(uint32), 1, f);

	(*data).resize(num);
	for (std::vector<float32>& d : (*data)) {
		f_写入文件(f, d);
	}
}

void f_file_备份保存文件(const std::string& path, fp_file_backupSave call, int32 备份次数, bool 是否备份保存) {
	std::filesystem::path tmpPath(path);

	bool 是否有老文件 = false;
	std::string 保存路径 = path;
	std::string 文件名 = tmpPath.stem().string();
	std::string 临时文件路径 = tmpPath.parent_path().string() + "/" + 文件名 + ".tmp";

	//目录是否存在
	if (std::filesystem::exists(tmpPath.parent_path().string()) == false) {
		std::filesystem::create_directories(tmpPath.parent_path().string());
	}

	if (是否备份保存) {
		if (std::filesystem::exists(tmpPath)) {
			保存路径 = 临时文件路径;
			是否有老文件 = true;
		}
	}


	FILE* f;
	f = fopen(保存路径.c_str(), "wb");
	if (f) {
		call(f);
		fclose(f);
	}
	
	
	std::filesystem::path 备份文件名 = tmpPath.parent_path().string() + "/" + 文件名 + ".tmp" + f_整数值转字符串(备份次数);
	if (std::filesystem::exists(备份文件名)) {
		std::filesystem::remove(备份文件名);
	}
	//--备份次数;
	for (--备份次数; 备份次数 >= 0; --备份次数) {
	//for (int32 i = 备份次数; i >= 0; --i) {
		备份文件名 = tmpPath.parent_path().string() + "/" + 文件名 + ".tmp" + f_整数值转字符串(备份次数);

		if (std::filesystem::exists(备份文件名)) {
			auto 新文件名 = tmpPath.parent_path().string() + "/" + 文件名 + ".tmp" + f_整数值转字符串(备份次数 + 1);
			std::filesystem::rename(备份文件名, 新文件名);
			是否有老文件 = true;
		}
	}

	if (std::filesystem::exists(tmpPath)) {
		备份文件名 = tmpPath.parent_path().string() + "/" + 文件名 + ".tmp" + f_整数值转字符串(0);
		std::filesystem::copy_file(tmpPath, 备份文件名);
	}

	//临时文件改层主文件名
	if (f_file_文件是否存在(保存路径) && f_file_文件是否存在(tmpPath.string())) {
		std::filesystem::rename(保存路径, tmpPath);
	}
	//if (std::filesystem::exists(保存路径) && std::filesystem::exists(tmpPath)) {
	//	std::filesystem::rename(保存路径, tmpPath);
	//}
	
}

void f_file_加载文件(const std::string& path, fp_file_backupSave call, bool 是否是否加载备份) {
	FILE* f;
	f = fopen(path.c_str(), "rb");
	if (f) {
		call(f);
		fclose(f);
	}
}







/*void f_写入序列到文件(FILE* f, const std::vector<vec3>& data) {
	uint32 num = data.size();
	fwrite(&num, sizeof(uint32), 1, f);

	fwrite(data.data(), sizeof(vec3), data.size(), f);
}

void f_读入文件(FILE* f, std::vector<vec3>* data) {
	uint32 num = 0;
	fread(&num, sizeof(uint32), 1, f);
	(*data).resize(num);

	fwrite((*data).data(), sizeof(vec3), num, f);
}*/



std::filesystem::path f_file_get路径(const std::filesystem::path& path) {
	std::filesystem::path tmpPath(path);

	if (std::filesystem::is_directory(tmpPath) == false) {
		return tmpPath.parent_path();
	}
	return path;
}

bool f_file_路径是否为目录(const std::filesystem::path& path) {
	std::error_code ec;
	return std::filesystem::is_directory(path, ec);
}






